//
//  woaOpenAPI+TTAdditions.m
//  tongtong
//
//  Created by xie bin on 12-3-31.
//  Copyright (c) 2012年 SNDA. All rights reserved.
//

#import "woaOpenAPI+TTAdditions.h"
#include <sys/socket.h> // Per msqr
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>
#import "ASIHTTPRequest.h"
#import "SBJson.h"

static woaConfigEx *_shareWoaConfigEx = nil;
static woaOpenAPI_Ex *_shareWoaOpenAPI_Ex = nil;

@implementation WoaOpenApi(TTAdditions)

- (woaConfigs *)getConfigs {
    return [woaOpenAPI_Ex shareWoaOpenAPI_Ex].configs;
}

@end

/******************************************************************************/
#pragma mark - woaOpenAPI_Ex
NSString * const kParamCodeEx = @"kParamCode";

@implementation woaOpenAPI_Ex

@synthesize configs = _configs;
@synthesize countryCodeIndex = _countryCodeIndex;
@synthesize resultCode = _resultCode;
@synthesize requestErrorCode = _requestErrorCode;
@synthesize delegate = _delegate;

+ (woaOpenAPI_Ex *)shareWoaOpenAPI_Ex {
    @synchronized(self) {
        if (nil == _shareWoaOpenAPI_Ex) {
            _shareWoaOpenAPI_Ex = [[woaOpenAPI_Ex alloc] init];
            // 第一次创建时直接下载配置数据去
            [_shareWoaOpenAPI_Ex getConfigData];
        }
    }
    return _shareWoaOpenAPI_Ex;
}

- (id)init
{
    self = [super init];
    if (self) {
        _countryCodeIndex = -1;
        _configs = [[woaConfigs alloc] initWithString:[woaConfigEx shareWoaConfigEx].configsData];
    }
    return self;
}

- (void)dealloc {
    self.delegate = nil;
}

- (NSString *)ASIHTTPRequestWithURLString:(NSString *)urlString isEncodeUrl:(BOOL)isEncodeUrl {
    // 返回responseString
    NSString *responseStr = nil;
    if (urlString) {
        NSString *encodeUrlString = urlString;
        if (isEncodeUrl == YES) {
            encodeUrlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        }// if
        
        NSURL *url = [NSURL URLWithString:encodeUrlString];
        // woaLog(url.absoluteString);
        self.requestErrorCode = 0;
        woaConfigEx * _woaCfg = [woaConfigEx shareWoaConfigEx];
        // 由于移动网络存在严重的不稳定性，这里增加重试机制，由于总是在线程中处理所以完全可以接受
        for (int r = 0; r < _woaCfg.maxRetryCount; r++) {
            ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:url];
            [request setTimeOutSeconds:_woaCfg.timeOutSeconds];
            [request startSynchronous];
            NSError *error = [request error];
            
            if (error == nil) {
                // 没有错误才算提交成功
                responseStr = [request responseString];
                if (responseStr == nil) {
                    responseStr = @"";
                }// if
            } else {
                self.requestErrorCode = [error code];
                //woaLog(([NSString stringWithFormat:@"error(%d):%@", [error code], error.localizedDescription]));
            }// if
            // woaLog(([NSString stringWithFormat:@"=>%@", responseStr]));
            if (nil == error) {
                break;
            }
        }// for r
    }
    return responseStr;
}

- (NSString *)ASIHTTPRequestWithURLString:(NSString *)urlString {
    return [self ASIHTTPRequestWithURLString:urlString isEncodeUrl:YES];
}


- (NSDictionary *)SBJsonParserWithString:(NSString *)jsonString {
    NSDictionary *result = nil; 
    @synchronized(self) {
        if (jsonString) {
            SBJsonParser *_parser = [[SBJsonParser alloc] init];
            id object = [_parser objectWithString:jsonString];
            if (object) {
                if ([object isKindOfClass:[NSDictionary class]]) {
                    result = (NSDictionary *)object;
                }// if
            } else {
                //woaLog(([NSString stringWithFormat:@"error: %@", _parser.error]));
            }// if
        }// if
    }
    return result;
}

- (void)getConfigDataInBackground:(NSDictionary *)dict {
    // 获取后台配置数据，成功则保存下次继续使用
    @autoreleasepool {
        NSInteger resultCode = wecError;
        NSString *v = @"";
        woaConfigs *wcs = nil;
        woaConfigEx * _woaCfg = [woaConfigEx shareWoaConfigEx];
        if (_woaCfg.configsData && ([_woaCfg.configsData length] > 0)) {
            wcs = [[woaConfigs alloc] initWithString:_woaCfg.configsData];
            v = [[NSString alloc] initWithString:wcs.version];
        }// if
        
        
        NSString *urlString = [NSString stringWithFormat:@"%@?configVersion=%@", _woaCfg.configUrl, v];
        NSString *responseStr = [self ASIHTTPRequestWithURLString:urlString];
        NSDictionary *dic = [self SBJsonParserWithString:responseStr];
        
        if (dic) {
            if ([dic objectForKey:@"configVersion"]) {
                // 有效的数据则记录下来
                _woaCfg.configsData = responseStr;
                resultCode = wecSuccess;
            }// if
        }
        
        self.resultCode = resultCode;
        NSDictionary *d =  [NSDictionary dictionaryWithObjectsAndKeys:
                            [NSNumber numberWithInt:resultCode], kParamCodeEx,
                            nil];
        [self performSelectorOnMainThread:@selector(doGetConfigDataResult:) withObject:d waitUntilDone:NO];
        
        
    }
}

- (void)getConfigData {
    [self performSelectorInBackground:@selector(getConfigDataInBackground:) withObject:nil];
}

- (void)doGetConfigDataResult:(NSDictionary *)dict {
    NSInteger resultCode = wecError;
    if (dict) {
        resultCode = [[dict objectForKey:kParamCodeEx] intValue];
        if ( wecSuccess == resultCode) {
            if (_configs) {
                _configs = nil;
            }// if
            woaConfigEx * _woaCfg = [woaConfigEx shareWoaConfigEx];
            _configs = [[woaConfigs alloc] initWithString:_woaCfg.configsData];
        }// if
    }// if
    
    if (dict && _delegate) {
        if ([_delegate respondsToSelector:@selector(configsChangedResult:)]) {
            [_delegate configsChangedResult:resultCode];
        }// if
    }// if
}

static BOOL isNumberChar(unichar c) {
    // 0-9的范围是48-57
    return ((c >= 48) && (c <=57));
}

static BOOL isPhoneChar(unichar c) {
    // # * +等特殊符号也允许 35 42 43
    return ((c == 35) || (c == 42) || (c == 43));
}

- (NSString *)filterNumberChar:(NSString *)str {
    // 过滤字符全部为数字的
    NSString *result = nil; 
    if (str) {
        unichar c;
        result = @"";
        for (int i = 0; i < [str length]; i++) {
            c = [str characterAtIndex:i];
            if (isNumberChar(c) || isPhoneChar(c)) {
                result = [result stringByAppendingFormat:@"%c", c];
            }// if
        }// for
    }// if
    return result;
}

- (NSString *)excludeZeroPlus:(NSString *)phone {
    // 去掉开头的+号、零等字符
    NSString *result = nil;
    if (phone) {
        NSInteger startIndex = 0;
        unichar c;
        for (int i = 0; i < [phone length]; i++) {
            c = [phone characterAtIndex:i];
            if ((NO == isPhoneChar(c)) && (48 != c)) {
                startIndex = i;
                break;
            }// if
        }// for
        if ((startIndex >= 0) && (startIndex < [phone length])) {
            NSRange r;
            r.location = startIndex;
            r.length = [phone length] - startIndex;
            result = [phone substringWithRange:r];
        }// if
    }// if
    return result;
}

- (NSString *)addCountryCode:(NSString *)phone {
    NSString *result = [self filterNumberChar:phone];
    NSInteger tmpCountryCode = -1;
    if (self.countryCodeIndex) {
        tmpCountryCode = self.countryCodeIndex;
    }// if
    
    if (-1 == tmpCountryCode) {
        tmpCountryCode = self.configs.defaultCountryIndex;
    }// if
    NSString *currentCountryCode = nil;
    if ((tmpCountryCode >= 0) && (tmpCountryCode < [self.configs.countryNames count])) {
        NSString *currentCountryName = [self.configs.countryNames objectAtIndex:tmpCountryCode];
        currentCountryCode = [self.configs.countryCode objectForKey:currentCountryName];
    }// if
    
    
    if (currentCountryCode && ([currentCountryCode length] > 0)) {
        /** 规则：
         1.默认传入的号码有国家代码则不做任何处理直接返回
         2.没有国家代码则添加
         例如：传入18621696852
         输出86-18621696852
         
         传入8618621696852
         输出86-18621696852
         
         传入+8618621696852
         输出86-18621696852
         */
        NSString *exResult = [self excludeZeroPlus:result];
        // woaLog(exResult);
        NSString *exCountryCode = [self excludeZeroPlus:currentCountryCode];
        NSRange r;
        r.location = 0;
        r.length = [exCountryCode length];
        if ([exResult length] > r.length) {
            NSString *preResult = [exResult substringWithRange:r];
            if ([preResult isEqualToString:exCountryCode]) {
                r.location = [exCountryCode length];
                r.length = [exResult length] - r.location;
                exResult = [exResult substringWithRange:r];
                result = [NSString stringWithFormat:@"%@-%@", currentCountryCode, exResult];
            } else {
                result = [NSString stringWithFormat:@"%@-%@", currentCountryCode, exResult];
            }// if
        }// if
    }// if
    
    return result;
}

@end

/******************************************************************************/
#pragma mark - woaConfigEx
// 简单异或的值
static Byte XorKeyValue = 153;
// 用于标识解密数据是否正确
static NSString *kXorDataTag = @"#woa2_ex#";
static NSString * const kConfigData = @"configData";

@interface woaConfigEx()
- (Byte)getMacXorKey;
- (void)checkCarrierType;
- (NSMutableDictionary *)loadFromFile;
@end

@implementation woaConfigEx

@synthesize isoCountryCode = _isoCountryCode;
@synthesize configsData = _configsData;
@synthesize configUrl = _configUrl;
@synthesize maxRetryCount = _maxRetryCount;
@synthesize timeOutSeconds = _timeOutSeconds;

+ (woaConfigEx *)shareWoaConfigEx {
    @synchronized(self) {
        if (nil == _shareWoaConfigEx) {
            _shareWoaConfigEx = [[woaConfigEx alloc] init];
        }
    }
    return _shareWoaConfigEx;
}

- (id)init
{
    self = [super init];
    if (self) {
        _configsData = nil;
        _configUrl = [[NSString alloc] initWithString:@"http://woa.sdo.com/woa/config/obtain.shtm"];
        _maxRetryCount = 3;
        _timeOutSeconds = 12;
        // 根据网卡的mac地址计算出用于加密的key,先简单xor下达到目的就行
        _macXorKey = [self getMacXorKey];
        NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
        libraryPath = [[NSString alloc] initWithString:[pathArray objectAtIndex:0]];
        woaDirectory = [[NSString alloc] initWithString:[libraryPath stringByAppendingPathComponent:@"woa2/"]];
        woaConfigPlist = [[NSString alloc] initWithString:[woaDirectory stringByAppendingPathComponent:@"sndawoa2ex.plist"]];
        // 不管3721把目录建上
        BOOL isDirectory = NO;
        NSFileManager *fileManager = [NSFileManager defaultManager];
        if (!([fileManager fileExistsAtPath:woaDirectory isDirectory:&isDirectory] && isDirectory)) 
            [fileManager createDirectoryAtPath:woaDirectory withIntermediateDirectories:YES attributes:nil error:nil];
        _dict = [self loadFromFile];
        [self checkCarrierType];
    }
    return self;
}

- (void)dealloc {
    if (_configsData) {
        _configsData = nil;
    }
}

- (void)setXorData:(NSMutableDictionary *)defaults strValue:(NSString *)str forKey:(NSString *)key {
    // 给字符串末尾加个标识方便判断是否解密失败
    NSString *tagStr = [str stringByAppendingString:kXorDataTag];
    NSData *EncodeAsData = [NSKeyedArchiver archivedDataWithRootObject:tagStr];
    NSMutableData *mutableData = [[NSMutableData alloc] initWithData:EncodeAsData];
    Byte *t = [mutableData mutableBytes];
    for (int i = 0; i < [mutableData length]; i++) {
        *t = *t ^ _macXorKey;// 简单异或下
        t++;
    }// for
    [defaults setObject:mutableData forKey:key];
}

- (Byte)getMacXorKey {
    Byte result = XorKeyValue;
    NSString *macAddress = [woaConfigEx macAddress];
    //TTLog(macAddress);
    if (macAddress && ([macAddress length] > 2)) {
        NSRange range;
        range.length = 2;            
        range.location = 0; 
        unsigned int x = 0;
        unsigned int m = 0;
        for (int i = 0; i < ([macAddress length] - 2); i++) {
            range.location = i;
            [[NSScanner scannerWithString:[macAddress substringWithRange:range]] scanHexInt:&m];
            x = (x + m) % 255;
            //NSLog(@"[%d]%@=%d", i,[macAddress substringWithRange:range], x);
        }// for
        result = x;
    }// if
    return result;
}

- (NSString *)getXorData:(NSMutableDictionary *)defaults forKey:(NSString *)key {
    NSString *result = @"";
    NSMutableData *deMutableData = [defaults objectForKey:key];
    
    if (deMutableData) {
        // 这里一定要拷贝一份的，否则是直接修改NSUserDefaults里对应key的数据了会导致不正确
        NSMutableData *deMutableCopyData = [NSMutableData dataWithBytes:[deMutableData mutableBytes] length:[deMutableData length]];
        //TTLog(([NSString stringWithFormat:@"key=%d data.len=%d", _macXorKey, [deMutableCopyData length]]));
        Byte *t = [deMutableCopyData mutableBytes];
        for (int i = 0; i < [deMutableCopyData length]; i++) {
            *t = *t ^ _macXorKey;// 简单异或下
            //NSLog(@"[%d]%d", i, *t);
            t++;
        }// for
        
        NSString *enKeyTagResult = nil;
        @try {
            // unarchiveObjectWithData会有异常的，try住
            enKeyTagResult = [NSKeyedUnarchiver unarchiveObjectWithData:deMutableCopyData];
        }
        @catch (NSException * e) {
            enKeyTagResult = nil;
            NSLog(@"getXorData Exception %@:%@ ->key=%d len=%d",[e name], [e reason], _macXorKey, [deMutableData length]);
        }
        if (enKeyTagResult) {
            NSRange r;
            r.length = [kXorDataTag length];
            if ([enKeyTagResult length] > r.length) {
                r.location = [enKeyTagResult length] - r.length;
                NSString *currentXorDataTag = [enKeyTagResult substringWithRange:r];
                if ([currentXorDataTag isEqualToString:kXorDataTag]) {
                    // 说明是正确解密的
                    r.location = 0;
                    r.length = [enKeyTagResult length] - r.length;
                    result = [enKeyTagResult substringWithRange:r];
                } 
            }// if            
        }// if
    }// if
    return result;
}

- (void)checkCarrierType {
    CTTelephonyNetworkInfo *info = [[CTTelephonyNetworkInfo alloc] init];
    CTCarrier *carrier = info.subscriberCellularProvider;
    // 根据返回的无线运营商国家代码，定位默认前辍
    // carrier.isoCountryCode http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
    if (carrier && carrier.isoCountryCode) {
        // 取无线运营商的国家代码
        _isoCountryCode = [[NSString alloc] initWithString:carrier.isoCountryCode];
    }// if
    // 在模拟器中返回nil，但在iPod中返回是长度为零的字符串
    if ((nil == _isoCountryCode) || (0 == [_isoCountryCode length])) {
        // 取当前时区的国家代码
        NSLocale *lc = [NSLocale currentLocale];
        NSArray *a = [lc.localeIdentifier componentsSeparatedByString:@"_"];
        if (a && (2 == [a count])) {
            if (_isoCountryCode) {
                _isoCountryCode = nil;
            }// if
            _isoCountryCode = [[NSString alloc] initWithString:[a objectAtIndex:1]];
        }// if
    }// if

}

- (BOOL)synchronize {
    BOOL result = NO;
    @synchronized(self) {
        if (_dict) {
            [_dict writeToFile:woaConfigPlist atomically:YES];
        }
    }
    return result;
}

- (NSMutableDictionary *)loadFromFile {
    NSMutableDictionary *result = nil;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:woaConfigPlist]) {
        @try {
            result = [NSMutableDictionary dictionaryWithContentsOfFile:woaConfigPlist];
        }
        @catch (NSException * e) {
            result = nil;
            NSLog(@"loadFromFile Exception %@:%@",[e name], [e reason]);
        }
        
    }// if
    if (_configsData) {
        _configsData = nil;
    }// if
    
    if (result) {// 加载成功
        _configsData = [self getXorData:result forKey:kConfigData];
    } else { // 不存在也提交个空的
        result = [[NSMutableDictionary alloc] init];
    }// if
    return result;
}

#pragma mark MAC
// Return the local MAC addy
// Courtesy of FreeBSD hackers email list
// Accidentally munged during previous update. Fixed thanks to mlamb.
+ (NSString *) macAddress
{
	int                 mib[6];
	size_t              len;
	char                *buf;
	unsigned char       *ptr;
	struct if_msghdr    *ifm;
	struct sockaddr_dl  *sdl;
	
	mib[0] = CTL_NET;
	mib[1] = AF_ROUTE;
	mib[2] = 0;
	mib[3] = AF_LINK;
	mib[4] = NET_RT_IFLIST;
	
	if ((mib[5] = if_nametoindex("en0")) == 0) {
		NSLog(@"Error: if_nametoindex error/n");
		return NULL;
	}
	
	if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
		NSLog(@"Error: sysctl, take 1");
		return NULL;
	}
	
	if ((buf = malloc(len)) == NULL) {
		NSLog(@"Could not allocate memory. error!");
		return NULL;
	}
	
	if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
		NSLog(@"Error: sysctl, take 2");
        free(buf);
		return NULL;
	}
	
	ifm = (struct if_msghdr *)buf;
	sdl = (struct sockaddr_dl *)(ifm + 1);
	ptr = (unsigned char *)LLADDR(sdl);
	// NSString *outstring = [NSString stringWithFormat:@"%02x:%02x:%02x:%02x:%02x:%02x", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
	NSString *outstring = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
	free(buf);
	return [outstring uppercaseString];
}

- (void)setConfigsData:(NSString *)value {
    @synchronized(self) {
        // if
        _configsData = [[NSString alloc] initWithString:value];
        [self setXorData:_dict strValue:_configsData forKey:kConfigData];
    }
    [self synchronize];    
    
}

- (NSString *)getConfgisData {
    return _configsData;
}

@end

/******************************************************************************/
#pragma mark - woaConfigs

// 默认的配置数据(直接从服务端现取的)
NSString * const kDefaultConfigs = @"{\"Result\": \"0\", \"configVersion\": \"8\", \"countryCode\": \"阿尔巴尼亚:355#阿尔及利亚:213#阿富汗:93#阿根廷:54#阿联酋:971#阿曼:968#埃及:20#埃塞俄比亚:251#安哥拉:244#澳大利亚:61#澳门:853#巴基斯坦:92#巴林:973#巴拿马:507#巴西:55#比利时:32#德国:49#俄罗斯:7#法国:33#菲律宾:63#韩国:82#荷兰:31#加拿大:1#加纳:233#柬埔寨:855#卡塔尔:974#科威特:965#老挝:856#黎巴嫩:961#罗马尼亚:40#马来西亚:60#美国:1#蒙古:976#秘鲁:51#缅甸:95#莫桑比克:258#墨西哥:52#南非:27#尼泊尔:977#尼日利亚:234#日本:81#沙特阿拉伯:966#苏丹:249#台湾:886#泰国:66#坦桑尼亚:255#土耳其:90#委内瑞拉:58#文莱:673#乌克兰:380#西班牙:34#希腊:30#香港:852#新加坡:65#新西兰:64#叙利亚:963#伊拉克:964#伊朗:98#意大利:39#印度:91#印度尼西亚:62#英国:44#约旦:962#越南:84#智利:56\", \"guid\": \"3f68e3bb3550473c98f4de594b9d17ff\", \"guidtime\": \"1348624326540\", \"intevalFirstTry\": 3000, \"intevalNextTry\": 1200, \"intevalReadSMS\": 1000, \"key\": \"24326539\", \"loginFeedbackPopTimes\": \"1\", \"resultCode\": \"0\", \"strongLogin\": 1, \"timeoutBindMobile\": \"604800000\", \"timeoutGuid\": \"28800000\", \"timeoutMustLoginFeedback\": \"600000000\", \"timeoutPreMobileLoginProcess\": \"3000\", \"timeoutReadSMS\": 30000, \"timeoutToExp\": \"600000\", \"timeoutTryLogin\": 40000 }";

NSString * const kChina = @"中国";
NSString * const kChina_HK = @"中国香港特别行政区";
NSString * const kChina_MO = @"中国澳门特别行政区";
NSString * const kChina_LA = @"老挝人民民主共和国";

@implementation woaConfigs

@synthesize version = _version;
@synthesize timeoutReadSMS = _timeoutReadSMS;
@synthesize timeoutTryLogin = _timeoutTryLogin;
@synthesize timeoutBindMobile = _timeoutBindMobile;
@synthesize timeoutGuid = _timeoutGuid;
@synthesize intevalFirstTry = _intevalFirstTry;
@synthesize intevalNextTry = _intevalNextTry;
@synthesize intevalReadSMS = _intevalReadSMS;
@synthesize countryCode = _countryCode;
@synthesize countryNames = _countryNames;
@synthesize defaultCountryIndex = _defaultCountryIndex;
@synthesize defaultCountryName = _defaultCountryName;

// 哎，从上面的kDefaultConfigs不难看出，文档中定义为数值型的仍然返回是的字符串(各种乱)
// 这里为冗错多写些代码吧！苦逼的事不少干啊～～～

- (NSString *)anyToNSString:(id)value {
    NSString *result = @"";
    if (value) {
        if ([value isKindOfClass:[NSString class]]) {
            result = [NSString stringWithString:value];
        } else {
            if ([value isKindOfClass:[NSNumber class]]) {
                result = [NSString stringWithFormat:@"%d", [(NSNumber *)value intValue]];
            }
        }// if
    }// if
    return result;
}

- (NSUInteger)andToNSUInteger:(id)value defaultValue:(NSUInteger)defaultValue {
    NSUInteger result = defaultValue;
    if (value) {
        if ([value isKindOfClass:[NSNumber class]]) {
            result = [(NSNumber *)value unsignedIntValue];
        } else {
            if ([value isKindOfClass:[NSString class]]) {
                result = [(NSString *)value integerValue];
            }
        }
    }
    return result;
}

- (void)processSetValue:(NSString *)cfgString {
    SBJsonParser *parser = [[SBJsonParser alloc] init];
    id object = [parser objectWithString:cfgString];
    if (object) {
        if ([object isKindOfClass:[NSDictionary class]]) {
            NSDictionary *dict = object;
            //woaLog(([NSString stringWithFormat:@"%@", NSStringFromClass([tmp class])]));
            _version = [self anyToNSString:[dict objectForKey:@"configVersion"]];
            _timeoutBindMobile = [self andToNSUInteger:[dict objectForKey:@"timeoutBindMobile"] defaultValue:1800];
            _timeoutReadSMS = [self andToNSUInteger:[dict objectForKey:@"timeoutReadSMS"] defaultValue:30000];
            _timeoutTryLogin = [self andToNSUInteger:[dict objectForKey:@"timeoutTryLogin"] defaultValue:20000];
            _timeoutGuid = [self andToNSUInteger:[dict objectForKey:@"timeoutGuid"] defaultValue:28800000];
            _intevalFirstTry = [self andToNSUInteger:[dict objectForKey:@"intevalFirstTry"] defaultValue:3000];
            _intevalNextTry = [self andToNSUInteger:[dict objectForKey:@"intevalNextTry"] defaultValue:1200];
            _intevalReadSMS = [self andToNSUInteger:[dict objectForKey:@"intevalReadSMS"] defaultValue:1000];
            _countryCode = nil;
            NSMutableDictionary *d = [[NSMutableDictionary alloc] initWithCapacity:10];
            NSMutableArray *cNames = [[NSMutableArray alloc] initWithCapacity:10];
            NSString *cs = [self anyToNSString:[dict objectForKey:@"countryCode"]];
            NSArray *ca = [cs componentsSeparatedByString:@"#"];
            NSInteger index;
            NSArray *cNameAndCode;
            for (NSString *c in ca) {
                cNameAndCode = [c componentsSeparatedByString:@":"];
                if (cNameAndCode && (2 == [cNameAndCode count])) {
                    //woaLog(([NSString stringWithFormat:@"%@ -> %@", [cNameAndCode objectAtIndex:0], [cNameAndCode objectAtIndex:1]]));
                    [d setObject:[cNameAndCode objectAtIndex:1] forKey:[cNameAndCode objectAtIndex:0]];
                    index = [cNames indexOfObject:[cNameAndCode objectAtIndex:0]];
                    if (NSNotFound == index) { // 排除重复
                        [cNames addObject:[cNameAndCode objectAtIndex:0]];
                    }// if
                }// if
            }// for 
            
            // 发现数据里居然没有 中国 只好自己加上
            index = [cNames indexOfObject:kChina];
            if (index == NSNotFound) {// 判断一下，避免重复添加
                [cNames addObject:kChina];
                [d setObject:@"86" forKey:kChina];
            }// if
            
            NSString *defaultCountryName = [woaConfigEx shareWoaConfigEx].isoCountryCode;
            if (defaultCountryName) {// 计算当前默认国家代码索引位置
                //NSLocale *l = [NSLocale currentLocale];
                // 必须这样才不受系统语言设置影响到，因为目前服务端总是返回简体中文的字符串
                NSLocale *l = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_ZH"];
                NSString *displayCountryName = [l displayNameForKey:NSLocaleCountryCode value:defaultCountryName];
                if (_defaultCountryName) {
                    _defaultCountryName = nil;
                }
                if (displayCountryName) {
                    _defaultCountryName = [[NSString alloc] initWithString: displayCountryName];
                    NSString *display2CountryName = nil;
                    if ([displayCountryName isEqualToString:kChina_HK]) {
                        // 特殊处理下，没办法，估计服务端不会这样配合iPhone端的
                        display2CountryName = @"香港";
                    }// if
                    if ([displayCountryName isEqualToString:kChina_MO]) {
                        // 特殊处理下，没办法，估计服务端不会这样配合iPhone端的
                        display2CountryName = @"澳门";
                    }// if
                    if ([displayCountryName isEqualToString:kChina_LA]) {
                        // 特殊处理下，没办法，估计服务端不会这样配合iPhone端的
                        display2CountryName = @"老挝";
                    }// if

                    for (int i=0; i < [cNames count]; i++) {
                        if ([displayCountryName isEqualToString:[cNames objectAtIndex:i]]) {
                            _defaultCountryIndex = i;
                            break;
                        }// if
                        if (display2CountryName) {
                            // 增加处理附加名称问题
                            if ([display2CountryName isEqualToString:[cNames objectAtIndex:i]]) {
                                _defaultCountryIndex = i;
                                break;
                            }// if
                        }// if
                    }// for
                }// if
            }// if
            
            _countryCode = [NSDictionary dictionaryWithDictionary:d];
            _countryNames = [NSArray arrayWithArray:cNames];
        }// if
    } else {
        //woaLog(([NSString stringWithFormat:@"error: %@", parser.error]));
        _version = nil;
    }// if
}

- (id)initWithString:(NSString *)cfgString {
    self = [super init];
    if (self) {
        // Initialization code here.
        _defaultCountryIndex = -1;
        if ((nil == cfgString) || (0 == [cfgString length])) {
            [self processSetValue:kDefaultConfigs];
        } else {
            [self processSetValue:cfgString];
        }// if
        
        // 再做一次有效性检查，避免因服务端问题导致获取失效数据
        if ((nil == _version) || (0 == [_version length])) {
            [self processSetValue:kDefaultConfigs];
        }// if
    }// if
    
    return self;    
}


@end
